# -*- coding: utf-8 -*-
'''
projecto- classe destinada a leitura da informação no sistema rebides
autor- Jose Jasnau Caeiro
data de criação do módulo- 7/03/2011
observações-

'''

# processamento de HTML através do parser BeautifulSoup
from BeautifulSoup import BeautifulSoup
import re

# biblioteca para acesso através de protocolos de Internet
import urllib2

from docente import Docente

class Rebides:
    '''
    Rebides
    representação dos dados retirados da base de dados online
    rebides para um determinado ano
    '''
    # url base do sistema Rebides
    URL_REBIDES = 'http://www.rebides.oces.mctes.pt/Rebides'

    # códigos indicativos 
    CODIGO_UNIVERSIDADES_PUBLICAS = '110'
    CODIGO_POLITECNICOS_PUBLICOS  = '120'
    CODIGO_INSTITUICOES_MILITARES = '130'
    CODIGO_UNIVERSIDADES_PRIVADAS = '210'
    CODIGO_POLITECNICOS_PRIVADOS  = '220'

    def gerar_url_ano(self):
        '''
        gerar_url_ano()
        geração 
        '''
        if self.ano < 10:
            self.url_ano = self.URL_REBIDES + '0' + str(self.ano) + '/'
        else:
            self.url_ano = self.URL_REBIDES + str(self.ano) + '/'
            pass
        pass
    
    def gerar_dicionarios_termos(self):
        self.dicionario_codigos = {}

        # universidades públicas
        url_tipo_instituicoes = self.url_ano + \
            'rebid_m1.asp?codr=' + \
            str(self.CODIGO_UNIVERSIDADES_PUBLICAS)

        self.dicionario_codigos[self.CODIGO_UNIVERSIDADES_PUBLICAS] = \
            ('Ensino Superior Público Universitário', 
             url_tipo_instituicoes)

        # politécnicos públicos
        url_tipo_instituicoes = self.url_ano + \
            'rebid_m1.asp?codr=' + \
            str(self.CODIGO_POLITECNICOS_PUBLICOS)

        self.dicionario_codigos[self.CODIGO_POLITECNICOS_PUBLICOS] = \
            ('Ensino Superior Público Politécnico',
             url_tipo_instituicoes)

        # instituições militares
        url_tipo_instituicoes = self.url_ano + \
            'rebid_m1.asp?codr=' + \
            str(self.CODIGO_INSTITUICOES_MILITARES)

        self.dicionario_codigos[self.CODIGO_INSTITUICOES_MILITARES] = \
            ('Ensino Superior Público Militar e Policial',
             url_tipo_instituicoes)

        # universidades privadas
        url_tipo_instituicoes = self.url_ano + \
            'rebid_m1.asp?codr=' + \
            str(self.CODIGO_UNIVERSIDADES_PRIVADAS)

        self.dicionario_codigos[self.CODIGO_UNIVERSIDADES_PRIVADAS] = \
            ('Ensino Superior Privado Universitário',
             url_tipo_instituicoes)

        # politécnicos privados
        url_tipo_instituicoes = self.url_ano + \
            'rebid_m1.asp?codr=' + \
            str(self.CODIGO_POLITECNICOS_PRIVADOS)

        self.dicionario_codigos[self.CODIGO_POLITECNICOS_PRIVADOS] = \
            ('Ensino Superior Privado Politécnico',
             url_tipo_instituicoes)
        
        pass

    def gerar_url_estabelecimento(self,
                                  codigo_tipo_instituicao,
                                  codigo_estabelecimento):
        if self.ano < 10:
            url_estabelecimento = \
                "http://www.rebides.oces.mctes.pt/rebides" + \
                "0" + \
                str(self.ano) + "/rebid_m2.asp?CodR=" + \
                str(codigo_tipo_instituicao) + \
                '&CodP=' + str(codigo_estabelecimento)
        else:
            url_estabelecimento = \
                "http://www.rebides.oces.mctes.pt/rebides" + \
                str(self.ano) + "/rebid_m2.asp?CodR=" + \
                str(codigo_tipo_instituicao) + \
                '&CodP=' + str(codigo_estabelecimento)
        return url_estabelecimento
                                  
    def __init__(self, ano):
        '''
        construtor da classe Rebides(ano)
        '''
        # ano - referencia ao ano a que se vai buscar a informação
        #       da base de dados Rebides
        self.ano = ano
        self.gerar_url_ano()
    
        self.gerar_dicionarios_termos()
        self.buscar_lista_instituicoes()
        
        codR = {}

        codR[ "110" ] = "Ensino Superior Público Universitário"
        codR[ "120" ] = "Ensino Superior Público Politécnico"
        codR[ "130" ] = "Ensino Militar e Policial"
        codR[ "210" ] = "Ensino Superior Particular e Cooperativo- Universidades"
        codR[ "220" ] = "Ensino Superior Particular e Cooperativo - Outros Estabelecimentos"
        
        # segundo nível da página do MCIES
        # códigos dos estabelecimentos de ensino
        
        codP = {}
        
        codP[ "110" ] = ("0100", "0110", "0130", \
                         "0200", "0201", "0202", \
                         "0203", "0204", "0205", \
                         "0300", "0400", "0500", \
                         "0501", "0502", "0503", \
                         "0504", "0505", "0506", \
                         "0507", "0508", "0600", \
                         "0700", "0701", "0702", \
                         "0703", "0704", "0705", \
                         "0706", \
                         "5302", "6600", "0801", \
                         "0802", "0803", "0804", \
                         "0805", "0806", "0807", \
                         "0900", "0901", "0902", \
                         "0903", "0904", "0905", \
                         "0906", "0908", \
                         "0910", "0911", "1000", \
                         "1101", "1102", "1103", \
                         "1104", "1105", "1106", \
                         "1107", "1108", "1109", \
                         "1110", "1111", "1113", \
                         "1114", "5402", "1200", \
                         "1300", "1400", "6800")
        
        codP[ "120" ] = ("7090", "7091", "3081", \
                         "3082", "3083", "7035", \
                         "3011", "3012", "3013", \
                         "3014", "7030", "7010", \
                         "7080", "7095", "3020", \
                         "3021", "3022", \
                         "3023", "7005", "3031", \
                         "3032", "3041", "3042", \
                         "3043", "3040", "3045", \
                         "7015", "3050", "3051", \
                         "3052", "3053", "3054", \
                         "3055", "7020", "3060", \
                         "3061", "3062", "3063", \
                         "3064", "3065", "7210", \
                         "3091", "3092", "3095", \
                         "7040", "3100", "3101", \
                         "3102", "3103", "3105", \
                         "7045", "3110", "3111", \
                         "3112", "3113", "3114", \
                         "3116", "3117", "3118", \
                         "7220", "3121", "3122", \
                         "3123", "7055", "3130", \
                         "3131", "3132", "3133", \
                         "3134", "3135", "3138", \
                         "7230", "3141", "3142", \
                         "3143", "3145", "7065", \
                         "3150", "3151", "3152", \
                         "3153", "3154", \
                         "3155", "3161", "3162", \
                         "3163", "3164", "7075", \
                         "3180", "3181", "3182", \
                         "3185", "3186", "7085", \
                         "3240", "3241", "3242", \
                         "3243", "7001", "7002", \
                         "7003", "7105", "7110")
        
        codP[ "130" ] = ("7500", "7505", "7510", \
                         "7515", "7520", "7525", \
                         "7530", "7540", "7620")
        
        codP[ "210" ] = ("2100", "2210", "2211", \
                         "2220", "2221", "2225", \
                         "2230", "2240", "2241", \
                         "2242", "2255", "2265", \
                         "2266", "2270", "2271", \
                         "2280", "2281", "2289", \
                         "2290", "2291", "2292", \
                         "2294", "2295", "2296", \
                         "2300", "2302", "2400", \
                         "2401", "2402", "2500", \
                         "2700", "2750", "2751", \
                         "2800", "4010", "4020", \
                         "4025", "4032", "4050", \
                         "4111", "4112", "4120", \
                         "4126", "4150", "4255", \
                         "4260", "4261", "4290", \
                         "4295", "4299", "4300", \
                         "4306", "4307", "4308", \
                         "4309", "4350", "4351", \
                         "4352", "4353", "4354", \
                         "4358", "4375", "4450", \
                         "4451", "4500", "4520")
        
        codP[ "220" ] = ("2215", "2216", "2217", \
                         "2701", "2752", "2753", \
                         "4002", "4005", "4011", \
                         "4065", "4068", "4069", \
                         "4074", "4076", "4077", \
                         "4078", "4079", "4080", \
                         "4081", "4085", "4089", \
                         "4091", "4093", "4095", \
                         "4096", "4097", "4098", \
                         "4099", "4101", "4102", \
                         "4103", "4104", "4105", \
                         "4106", "4108", "4109", \
                         "4115", "4125", "4141", \
                         "4155", "4156", "4157", \
                         "4160", "4200", "4220", \
                         "4270", "4271", "4275", \
                         "4277", "4280", "4283", \
                         "4292", "4298", "4303", \
                         "4305", "4380", "4385", \
                         "4425", "4440", "4441", \
                         "4442", "4460", "4530", \
                         "4531", "4090")
        
        for elemento in codR:
            for elemento2 in codP[elemento]:
                codigo_tipo_instituicao = elemento
                codigo_estabelecimento = elemento2
                url_estabelecimento = \
                    self.gerar_url_estabelecimento(codigo_tipo_instituicao,
                                       codigo_estabelecimento)
                print url_estabelecimento
                self.buscar_dados_estabelecimento(url_estabelecimento)
                pass

    def abrir_conexao(self, url):
        '''
        abre a conexão para este url
        '''
        try:
            ficheiro = urllib2.urlopen( url )
            return ficheiro
        except:
            
            print "ERRO ", url
            pass
        pass
    
    def ler_dados(self, ficheiro):
        '''
        ler os dados correspondentes a um ficheiro
        '''
        try:
            dados = ficheiro.read()
            ficheiro.close()
            return dados
        except:
            print "ERRO"
            return
        pass

    def processar_dados_tipos_instituicao(self, dados):
        '''
        '''
        soup = BeautifulSoup(dados)
        lista = []
        
        # print soup.prettify()
        ll = soup.findAll('a')
        for l in ll:
            try:
                newsoup = BeautifulSoup(u"" + unicode(l))
                estabelecimento = newsoup.contents[0].contents[0]
                
                b = newsoup.a
                codigos =  b['href']
                
                m = re.search('(?<=CodP=)\w+', codigos)
                codigo_estabelecimento=m.group(0)
                
                lista.append( (estabelecimento, codigo_estabelecimento))
            except:
                print "ERRO "
                pass
            pass
        return lista

    def contar_numero_instituicoes(self):
        self.dicionario_numero_instituicoes = {}
        for codigo_tipo_instituicao, lista in \
                self.dicionario_instituicoes.iteritems():
            contador = 0
            for x, y in lista:
                contador += 1
                pass
            self.dicionario_numero_instituicoes[codigo_tipo_instituicao] \
                = contador
            pass
        
    def imprimir_numero_instituicoes(self):
        print "Ano: ", self.ano
        for chave, valor in self.dicionario_numero_instituicoes.iteritems():
            print self.dicionario_codigos[chave][0], valor        
            pass
        pass

    def buscar_lista_instituicoes(self):
        '''
        este método permite buscar a lista das instituições de
        ensino superior existentes num determinado ano
        '''
        self.dicionario_instituicoes = {}
        for cod_tipo_instituicao, (tipo_instituicao, url_tipo_instituicao) \
                in self.dicionario_codigos.iteritems():
            ficheiro = self.abrir_conexao(url_tipo_instituicao)
            dados = self.ler_dados(ficheiro)
        
            self.dicionario_instituicoes[ cod_tipo_instituicao ]=\
                self.processar_dados_tipos_instituicao(dados)
            pass
        pass
    
    def buscar_dados_estabelecimento(self, url_estabelecimento):
        '''
        busca os dados dos docentes relativos a cada estabelecimento
        '''
        # abre a conexão para este url
        #print "Conexao aberta: ", url_estabelecimento
        try:
            f = urllib2.urlopen( url_estabelecimento )
        except:
            print "erro: ", url_estabelecimento
            pass

        # lê os dados correspondentes a este estabelecimento de ensino
        try:
            dados = f.read()
            f.close()
        except:
            print "barracada"
            return

        soup = BeautifulSoup(dados)
        contador = 0
        lista = []
        
        
        for conteudo_docente in soup('tr'):
            docente = Docente()
            # print "contagem", contador
            # campos = conteudo_docente.find('td', {"class" : "col1"})
            # print campos
            # print campos.find("td", {"class" : "col1"})
            # print conteudo_docente.contents[1].contents[0], contador
            
            # selecciona o nome completo do docente
            nome = conteudo_docente.contents[1].contents[0]
            grau = conteudo_docente.contents[3].contents[0]
            grau = grau.lstrip()
            curso = conteudo_docente.contents[5].contents[0]
            curso = curso.lstrip()
            
            if conteudo_docente.contents[7].contents[0] != u'&nbsp;':
                categoria = conteudo_docente.contents[7].contents[0]
                categoria = categoria.lstrip()

            if conteudo_docente.contents[9].contents[0] != u'&nbsp;':
                regime = conteudo_docente.contents[9].contents[0]
                regime = regime.lstrip()
            
            if nome == u'&nbsp;' :
                grau = conteudo_docente.contents[3].contents[0]
                grau = grau.lstrip()
            else:
                nome_completo = nome
                nome_completo = nome_completo.expandtabs()
                novo_completo = re.sub('\015', '', nome_completo)
                nome_completo = novo_completo.lstrip()
                contador += 1
                pass
            print grau.encode('utf-8'), nome_completo.encode('utf-8'), \
                curso.encode('utf-8')
            print categoria.encode('utf-8')
            print regime.encode('utf-8')
            pass
        print "Número de docentes: ", contador
        '''
        for teste in soup('tr'):
            try:
                docente = Docente()
                if teste.contents[1].contents[0] != u'&nbsp;':
                    nome = teste.contents[1].contents[0]
                    nome = nome.lstrip()
                    docente.nome = nome
                    pass
                
                grau = teste.contents[3].contents[0]
                grau = grau.lstrip()
                docente.grau = grau
                
                curso = teste.contents[5].contents[0]
                curso = curso.lstrip()
                docente.curso = curso
                
                categoria = teste.contents[7].contents[0]
                categoria = categoria.lstrip()
                
                regime = teste.contents[9].contents[0]
                regime = regime.lstrip()
                
                
                if categoria != u'&nbsp;':
                    docente.categoria = categoria
                    docente.regime = regime
                    print nome, grau, curso, categoria, regime
                    print docente
                else:
                    print nome, grau, curso
                    print docente
                
            except:
                print "erros"
            pass
        '''
        contador = contador + 1
        if contador > 10:
            return lista
        return lista
    pass


#for ano in range(0,10):
#    print "Ano: ", ano
#    rebides = Rebides(ano)


#     rebides.contar_numero_instituicoes()
#     rebides.imprimir_numero_instituicoes()
#     pass


